Gregory Szorc <gregory.szorc@gmail.com> [Wed, 04 Apr 2018 11:37:07 -0700] rev 37337
tests: add test extension implementing custom filelog storage
In order to better support partial clones, we'll need alternate
repository storage mechanisms that aren't based on revlogs.
Today, the interface for repository storage isn't very well defined.
And there are various layering violations and assumptions made
throughout the code that storage is backed by revlogs.
In order to support alternate storage mechanisms, we'll need to
formally declare and adhere to interfaces for storage. This will
be a long, arduous process.
This commit creates an extension that implements non-revlog storage
for files. It defines a custom type that quacks like the existing
revlog/filelog API but isn't backed by a revlog. The backing storage
is - for simplicity reasons - a CBOR index and per-node files
representing fulltext data.
The localrepository class is modified so file(f) returns instances of
this class instead of filelog instances.
The purpose of this extension is to tease out what the actual filelog
interface is - based on running the test harness - so we can formalize
that interface and then implement a *real* alternate storage backend.
Using `run-tests.py --extra-config-opt` to run the test harness
with this extension enabled yields 83 failures out of 634 ran
tests.
The most common test failures are due to:
* Issues with `hg verify`
* LFS and largefiles (probably flags processing related)
* Narrow.
* Any test touching or inspecting individual filelog paths.
* help and error output that is confused by the presence of an
extension.
* `hg debug*` commands doing low-level, revlog-y things.
An 88% pass rate is pretty good for an initial implementation if you
ask me!
There is a bit of duplicate code in the new extension. That's by
design: a point of this code is to tease out dependencies on revlog.
That being said, there is opportunity to consolidate code by moving
things out of the revlog API. For example, DAG traversal operations
don't necessarily need to be implemented at the storage level. (Although
for performance reasons they probably do.) Once we have a more
well-defined interface, we could probably define the default
implementations in terms of the base interface, pull those in via
class inheritance, and have implementations override with faster
versions if they so choose. (Or something like that.) But for now,
the duplicate code should be acceptable.
Differential Revision: https://phab.mercurial-scm.org/D3029
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 03 Apr 2018 13:56:09 -0700] rev 37336
tests: use `hg unbundle` instead of `hg pull` in some tests
`hg pull <bundle>` uses the special "bundlerepo" repository. The
bundlerepo code makes many assumptions about the storage of
repositories. It will be difficult to teach bundlerepo to use
non-revlog storage before a better storage interface is established.
Many test failures using our "simple store" are related to
bundlerepo: the simple store just isn't compatible with bundlerepo
because of storage assumptions in bundlerepo.
In order to mitigate the impact of bundlerepo on our code base,
this commit changes various tests to use `hg unbundle` instead
of `hg pull`. This bypasses the bundlerepo code.
Tests exercising exchange functionality have not been altered, as
they should be using `hg pull` and going through the bundlerepo
code paths.
Differential Revision: https://phab.mercurial-scm.org/D3059
Martin von Zweigbergk <martinvonz@google.com> [Wed, 04 Apr 2018 09:41:18 -0700] rev 37335
hgweb: use revsymbol() for creating context from changeid
These seem to be for looking up a revision that can come from the
user, so revsymbol() is the right method to call (
0194dac7 has more
information about my plans for repo[x]).
Differential Revision: https://phab.mercurial-scm.org/D3075
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 23:00:41 -0700] rev 37334
hgweb: inline changeidctx()
Differential Revision: https://phab.mercurial-scm.org/D3074
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 21:50:42 -0700] rev 37333
hgweb: drop support for "manifest" parameter
AFAICT (but note that this is the first time I look at hgweb code),
the "mercurial" query parameter was removed from rendered pages in
36fa5db79dd5 (hgweb: convert gitweb to NWI, 2006-10-05). Search for
"manifest=" in that diff to see why I think it was removed. It's about
time we stop looking for the parameter in requests.
Differential Revision: https://phab.mercurial-scm.org/D3073
Martin von Zweigbergk <martinvonz@google.com> [Wed, 04 Apr 2018 10:32:48 -0700] rev 37332
rebase: use single transaction when running in memory
rebase.singletransaction make rebase noticeably faster (~20% in a test
I just ran). It is not enabled by default because it risks losing
information if it aborts (see `hg help rebase`). When running rebase
with the experimental in-memory option on, rebase is first attempted
in memory, and if any conflicts occur, it restarts, this time writing
to disk. Thus, it should be safe to turn on single-transaction mode
for the in-memory phase.
Differential Revision: https://phab.mercurial-scm.org/D3076
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 03 Apr 2018 13:16:12 -0700] rev 37331
bundlerepo: use super() when calling file()
We should be calling the default method, not reimplementing it.
Differential Revision: https://phab.mercurial-scm.org/D3058
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 03 Apr 2018 18:20:10 -0700] rev 37330
tests: remove superfluous config setting
format.usegeneraldelta defaults to true.
Differential Revision: https://phab.mercurial-scm.org/D3057
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 22:30:25 +0900] rev 37329
templater: mark .joinfmt as a private attribute
Yuya Nishihara <yuya@tcha.org> [Mon, 19 Mar 2018 20:32:06 +0900] rev 37328
obsutil: make obsfateprinter() less dependent on templater
joinfmt() is defined as 'lambda x: scmutil.formatchangeid(repo[x])' in
showsuccsandmarkers().
Function arguments are reordered so they look more normal.
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 22:06:31 +0900] rev 37327
templater: abstract away from joinfmt
Future patches will add a wrapper for a list of template mappings, which
will implement a custom join() something like {join(mappings % template)}.
The original join() function is broken down as follows:
if hasattr(joinset, 'joinfmt'):
# hybrid.join() where values must be a list or a dict
joinitems((joinfmt(x) for x in values), sep)
elif isinstance(joinset, templateutil.wrapped):
# mappable.join()
show()
else:
# a plain list, a generator, or a byte string; joinfmt was identity()
joinset = templateutil.unwrapvalue(context, joinset)
joinitems(pycompat.maybebytestr(joinset), joiner)
Yuya Nishihara <yuya@tcha.org> [Tue, 20 Mar 2018 23:16:28 +0900] rev 37326
templater: micro-optimize join() with empty separator
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 21:42:27 +0900] rev 37325
templater: factor out generator of join()-ed items
Prepares for defining join() behavior per wrapped types and getting rid
of the public joinfmt attribute.
Yuya Nishihara <yuya@tcha.org> [Sun, 18 Mar 2018 23:24:50 +0900] rev 37324
templater: pass context to itermaps() for future extension
Unlike show() and tovalue(), a base mapping isn't passed to itermaps()
since it is the function to generate a partial mapping.
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 21:21:50 +0900] rev 37323
templater: define interface for objects which act as iterator of mappings
Yuya Nishihara <yuya@tcha.org> [Wed, 04 Apr 2018 23:26:49 +0900] rev 37322
stringutil: drop escapedata() in favor of escapestr()
They are quite similar. Let's choose one that uses standard Python escape.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 30 Mar 2018 18:57:13 -0700] rev 37321
peer: make ui an attribute
With abc interfaces, instance attributes could not satisfy
@abc.abstractproperty requirements because interface conformance
was tested at type creation time. When we created the abc
peer interfaces, we had to make "ui" a @property to satisfy
abc.
Now that peer interfaces are using zope.interface and there is no
import time validation (but there are tests validating instances
conform to the interface), we can go back to using regular object
attributes.
Differential Revision: https://phab.mercurial-scm.org/D3069
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 30 Mar 2018 18:53:17 -0700] rev 37320
repository: port peer interfaces to zope.interface
zope.interface is superior. Let's switch to it.
Unlike abc, which defines interfaces through a base class,
zope.interface uses different types for interfaces and for
implementations. So, we had to invent some new types to hold the
interfaces in order to separate the interface from its default
implementation.
The names here could probably be better. I've been wanting to
overhaul the peer interface for a while. And wire protocol version
2 will force that work. So anticipate a refactoring of these
interfaces in later commits.
With this commit, we no longer test abc interfaces in
test-check-interfaces.py, so code for that has been removed.
Differential Revision: https://phab.mercurial-scm.org/D3068
# no-check-commit because of stream_out()
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 30 Mar 2018 14:52:32 -0700] rev 37319
wireproto: convert human output frames to CBOR
This is easier than rolling our own encoding format.
As a bonus, some of our artificial limits around lengths of
things went away because we are no longer using fixed length
fields to hold sizes.
Differential Revision: https://phab.mercurial-scm.org/D3067
Pulkit Goyal <7895pulkit@gmail.com> [Mon, 02 Apr 2018 17:06:42 +0530] rev 37318
py3: use pycompat.bytestr() intsead of str
Differential Revision: https://phab.mercurial-scm.org/D3071
Pulkit Goyal <7895pulkit@gmail.com> [Mon, 19 Mar 2018 12:46:56 +0530] rev 37317
py3: use print as a function in tests/test-walk.t
Differential Revision: https://phab.mercurial-scm.org/D3070
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 13:19:35 -0700] rev 37316
repo: remove now-unused changectx() method (API)
repo.changectx(x) was just a synonym for repo[x], so any extensions
that fail due to this commit should switch over to that form.
Differential Revision: https://phab.mercurial-scm.org/D3037
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 15:08:09 -0700] rev 37315
localrepo: use revsymbol() in lookup()
lookup() seems to be about looking up a revision based on a symbol
that may come from the user (via the wire protocol), so revsymbol() is
appropriate here.
Differential Revision: https://phab.mercurial-scm.org/D3055
Martin von Zweigbergk <martinvonz@google.com> [Sun, 01 Apr 2018 23:29:51 -0700] rev 37314
histedit: avoid repo.lookup() for converting revnum to nodeid
Differential Revision: https://phab.mercurial-scm.org/D3054
Martin von Zweigbergk <martinvonz@google.com> [Sun, 01 Apr 2018 23:27:50 -0700] rev 37313
outgoing: avoid repo.lookup() for converting revnum to nodeid
Differential Revision: https://phab.mercurial-scm.org/D3053
Martin von Zweigbergk <martinvonz@google.com> [Sun, 01 Apr 2018 23:21:17 -0700] rev 37312
bisect: avoid repo.lookup() for converting revnum to nodeid
Differential Revision: https://phab.mercurial-scm.org/D3052
Martin von Zweigbergk <martinvonz@google.com> [Sun, 01 Apr 2018 23:19:37 -0700] rev 37311
transplant: avoid repo.lookup() for converting revnum to nodeid
Differential Revision: https://phab.mercurial-scm.org/D3051
Martin von Zweigbergk <martinvonz@google.com> [Sun, 01 Apr 2018 23:10:25 -0700] rev 37310
tests: avoid repo.lookup() for converting revnum to nodeid
Differential Revision: https://phab.mercurial-scm.org/D3050
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 15:14:31 -0700] rev 37309
bundle: consistently keep a list of stringified revisions in "revs"
Before this patch, "revs", in the "not base" branch, would be a list
of mixed integral revnums, hex nodeids, and branch names. After this
patch, they're all strings. They can still be a mix of hex nodeids and
branch names, but the important thing for my future patches is that
they're consistently in string form.
Differential Revision: https://phab.mercurial-scm.org/D3049
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 15:10:41 -0700] rev 37308
bundle: avoid repo.lookup() for converting revnum to nodeid
Differential Revision: https://phab.mercurial-scm.org/D3048
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 14:39:21 -0700] rev 37307
push: avoid using repo.lookup() for converting to nodeid
repo.lookup(x) currently simply does repo[x].node(), which supports
various types of inputs. As I explained in
0194dac77c93 (scmutil: add
method for looking up a context given a revision symbol, 2018-04-02),
I'd like to split that up so we use the new scmutil.revsymbol() for
string inputs repo[x] for integer revnums and binary nodeids. Since
repo.lookup() seems to exist in order to serve peer.lookup(), I think
it should be calling revsymbol. However, we have several callers that
use repo.lookup() with something that's not a string, so we need to
remove those first. This patch starts doing that. Many more will
follow.
Differential Revision: https://phab.mercurial-scm.org/D3047
Yuya Nishihara <yuya@tcha.org> [Tue, 03 Apr 2018 22:24:50 +0900] rev 37306
addremove: pass command-level similarity value down to scmutil.addremove()
Since we've changed to carry a similarity value by opts dict, it makes sense
to leave a string '0'-'100' value unmodified.
Augie Fackler <augie@google.com> [Tue, 03 Apr 2018 13:37:57 -0400] rev 37305
setup: add overlooked hgext.infinitepush package declaration
Will fix infinitepush tests that have been failing when run without --local.
Differential Revision: https://phab.mercurial-scm.org/D3038
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 09:12:15 -0700] rev 37304
tests: remove dependence on repo.changectx()
This was one of few remaining uses of repo.changectx() in core.
Differential Revision: https://phab.mercurial-scm.org/D3036
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 08:55:49 -0700] rev 37303
log: remove dependence on repo.changectx()
This was one of few remaining uses of repo.changectx() in core.
Differential Revision: https://phab.mercurial-scm.org/D3035
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 08:55:16 -0700] rev 37302
verify: remove dependence on repo.changectx()
This was one of few remaining uses of repo.changectx() in core.
Differential Revision: https://phab.mercurial-scm.org/D3034
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 08:46:58 -0700] rev 37301
bookmarks: switch from repo.changectx('.') to repo['.']
The two forms are synonymous and the new form is by far the more
common form.
Differential Revision: https://phab.mercurial-scm.org/D3033
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 14:52:57 -0700] rev 37300
stringutil: add function to pretty print an object
This is inspired by the pprint() module/function (which we can't
use because the output is different on Python 2 and 3 - namely the
use of b'' literals).
We hook it up to `hg debugwireproto` for printing the response to
a wire protocol command.
This foreshadows future peer work, which will support decoding
CBOR responses into rich data structures.
Differential Revision: https://phab.mercurial-scm.org/D2987
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 13:30:24 -0700] rev 37299
wireproto: add frame flag to denote payloads as CBOR
We may eventually want a separate frame type for this. But for
now this is the easiest to implement.
Differential Revision: https://phab.mercurial-scm.org/D2986
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 13:01:28 -0700] rev 37298
wireproto: implement custom __repr__ for frame
This version won't print the full payload (which could be large).
It also prints human friendly values for types and flags.
Differential Revision: https://phab.mercurial-scm.org/D2985
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 12:44:35 -0700] rev 37297
keepalive: implement readinto()
This is part of the standard I/O interface. It is used by the framing
protocol. So we need to implement it so frames can be decoded.
Differential Revision: https://phab.mercurial-scm.org/D2984
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 23 Mar 2018 16:24:53 -0700] rev 37296
wireproto: port protocol handler to zope.interface
zope.interface is superior to the abc module. Let's port to it.
As part of this, we add tests for interface conformance for
classes implementing the interface.
Differential Revision: https://phab.mercurial-scm.org/D2983
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 10:40:41 -0700] rev 37295
wireproto: separate commands tables for version 1 and 2 commands
We can't easily reuse existing command handlers for version 2
commands because the response types will be different. e.g. many
commands return nodes encoded as hex. Our new wire protocol is
binary safe, so we'll wish to encode nodes as binary.
We /could/ teach each command handler to look at the protocol
handler and change behavior based on the version in use. However,
this would make logic a bit unwieldy over time and would make
it harder to design a unified protocol handler interface. I think
it's better to create a clean break between version 1 and version 2
of commands on the server.
What I imagine happening is we will have separate @wireprotocommand
functions for each protocol generation. Those functions will parse the
request, dispatch to a common function to process it, then generate
the response in its own, transport-specific manner.
This commit establishes a separate table for tracking version 1
commands from version 2 commands. The HTTP server pieces have been
updated to use this new table.
Most commands are marked as both version 1 and version 2, so there is
little practical impact to this change.
A side-effect of this change is we now rely on transport registration
in wireprototypes.TRANSPORTS and certain properties of the protocol
interface. So a test had to be updated to conform.
Differential Revision: https://phab.mercurial-scm.org/D2982
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 10:12:02 -0700] rev 37294
wireproto: mark SSHv2 as a version 1 transport
The version component is used for filtering/routing wire protocol
commands to their proper handler. The actual version 2 of the wire
protocol commands will use a different encoding of responses. We
already have tests using the version 2 SSH transport and version 2
of the wire protocol commands won't be implemented atomically.
This commit marks the SSHv2 transport as version 1 so it will
still invoke the version 1 commands. Once the commands are all
implemented in version 2, we can restore its proper behavior.
Some tests had to be disabled as a result of this change.
Differential Revision: https://phab.mercurial-scm.org/D2981
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 14:05:29 -0700] rev 37293
wireproto: stop aliasing wire protocol types (API)
We generally shy away from aliasing module symbols. I think I
was keeping this around for API compatibility. We've already made
tons of other API breaks in the wire protocol code this release.
What's one more?
.. api::
``wireproto`` module no longer re-exports various types used to
define responses to wire protocol commands. Access these types
from the ``wireprototypes`` module.
Differential Revision: https://phab.mercurial-scm.org/D2979
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 26 Mar 2018 14:34:32 -0700] rev 37292
wireproto: use CBOR for command requests
Now that we're using CBOR in the new wire protocol, let's convert
command requests to it.
Before I wrote this patch and was even thinking about CBOR, I was
thinking about how commands should be issued and came to the
conclusion that we didn't need separate frames to represent the
command name from its arguments. I already had a partially
completed patch prepared to merge the frames.
But with CBOR, it makes the implementation a bit simpler because
we don't need to roll our own serialization.
The changes here are a bit invasive. I tried to split this into
multiple commits to make it easier to review. But it was just too
hard.
* "command name" and "command argument" frames have been collapsed
into a "command request" frame.
* The flags for this new frame are totally different.
* Frame processing has been overhauled to reflect the new order
of things.
* Test fallout was significant. A handful of tests were removed.
Altogether, I think the new code is simpler. We don't have
complicated state around receiving commands. We're either receiving
command request frames or command data frames. We /could/
potentially collapse command data frames into command request
frames. Although I'd have to think a bit more about this before
I do it.
Differential Revision: https://phab.mercurial-scm.org/D2951
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 26 Mar 2018 10:50:36 -0700] rev 37291
wireproto: define frame to represent progress updates
Today, a long-running operation on a server may run without any sign
of progress on the client. This can lead to the conclusion that the
server has hung or the connection has dropped. In fact, connections
can and do time out due to inactivity. And a long-running server
operation can result in the connection dropping prematurely because
no data is being sent!
While we're inventing the new wire protocol, let's provide a mechanism
for communicating progress on potentially expensive server-side events.
We introduce a new frame type that conveys "progress" updates. This
frame type essentially holds the data required to formulate a
``ui.progress()`` call.
We only define the frame right now. Implementing it will be a bit of
work since there is no analog to progress frames in the existing
wire protocol. We'll need to teach the ui object to write to the
wire protocol, etc.
The use of a CBOR map may seem wasteful, as this will encode key
names in every frame. This *is* wasteful. However, maps are
extensible. And the intent is to always use compression via
streams. Compression will make the overhead negligible since repeated
strings will be mostly eliminated over the wire.
Differential Revision: https://phab.mercurial-scm.org/D2902
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 28 Mar 2018 15:05:39 -0700] rev 37290
wireproto: syntax for encoding CBOR into frames
We just vendored a library for encoding and decoding the CBOR
data format. While the intent of that vendor was to support state
files, CBOR is really a nice data format. It is extensible and
compact.
I've been feeling dirty inventing my own data formats for
frame payloads. While custom formats can always beat out a generic
format, there is a cost to be paid in terms of implementation,
comprehension, etc. CBOR is compact enough that I'm not too
worried about efficiency loss. I think the benefits of using
a standardized format outweigh rolling our own formats. So
I plan to make heavy use of CBOR in the wire protocol going
forward.
This commit introduces support for encoding CBOR data in frame
payloads to our function to make a frame from a human string.
We do need to employ some low-level Python code in order to
evaluate a string as a Python expression. But other than that,
this should hopefully be pretty straightforward.
Unit tests for this function have been added.
Differential Revision: https://phab.mercurial-scm.org/D2948
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 26 Mar 2018 13:59:56 -0700] rev 37289
wireproto: explicit API to create outgoing streams
It is better to create outgoing streams through the reactor so the
reactor knows about what streams are active and can track them
accordingly.
Test output changes slightly because frames from subsequent responses
no longer have the "stream begin" stream flag set because the stream
is now used across all responses.
Differential Revision: https://phab.mercurial-scm.org/D2947
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 26 Mar 2018 11:00:16 -0700] rev 37288
wireproto: add streams to frame-based protocol
Previously, the frame-based protocol was just a series of frames,
with each frame associated with a request ID.
In order to scale the protocol, we'll want to enable the use of
compression. While it is possible to enable compression at the
socket/pipe level, this has its disadvantages. The big one is it
undermines the point of frames being standalone, atomic units that
can be read and written: if you add compression above the framing
protocol, you are back to having a stream-based protocol as opposed
to something frame-based.
So in order to preserve frames, compression needs to occur at
the frame payload level.
Compressing each frame's payload individually will limit compression
ratios because the window size of the compressor will be limited
by the max frame size, which is 32-64kb as currently defined. It
will also add CPU overhead, as it is more efficient for compressors
to operate on fewer, larger blocks of data than more, smaller blocks.
So compressing each frame independently is out.
This means we need to compress each frame's payload as if it is part
of a larger stream.
The simplest approach is to have 1 stream per connection. This
could certainly work. However, it has disadvantages (documented below).
We could also have 1 stream per RPC/command invocation. (This is the
model HTTP/2 goes with.) This also has disadvantages.
The main disadvantage to one global stream is that it has the very
real potential to create CPU bottlenecks doing compression. Networks
are only getting faster and the performance of single CPU cores has
been relatively flat. Newer compression formats like zstandard offer
better CPU cycle efficiency than predecessors like zlib. But it still
all too common to saturate your CPU with compression overhead long
before you saturate the network pipe.
The main disadvantage with streams per request is that you can't
reap the benefits of the compression context for multiple requests.
For example, if you send 1000 RPC requests (or HTTP/2 requests for
that matter), the response to each would have its own compression
context. The overall size of the raw responses would be larger because
compression contexts wouldn't be able to reference data from another
request or response.
The approach for streams as implemented in this commit is to support
N streams per connection and for streams to potentially span requests
and responses. As explained by the added internals docs, this
facilitates servers and clients delegating independent streams and
compression to independent threads / CPU cores. This helps alleviate
the CPU bottleneck of compression. This design also allows compression
contexts to be reused across requests/responses. This can result in
improved compression ratios and less overhead for compressors and
decompressors having to build new contexts.
Another feature that was defined was the ability for individual frames
within a stream to declare whether that individual frame's payload
uses the content encoding (read: compression) defined by the stream.
The idea here is that some servers may serve data from a combination
of caches and dynamic resolution. Data coming from caches may be
pre-compressed. We want to facilitate servers being able to essentially
stream bytes from caches to the wire with minimal overhead. Being
able to mix and match with frames are compressed within a stream
enables these types of advanced server functionality.
This commit defines the new streams mechanism. Basic code for
supporting streams in frames has been added. But that code is
seriously lacking and doesn't fully conform to the defined protocol.
For example, we don't close any streams. And support for content
encoding within streams is not yet implemented. The change was
rather invasive and I didn't think it would be reasonable to implement
the entire feature in a single commit.
For the record, I would have loved to reuse an existing multiplexing
protocol to build the new wire protocol on top of. However, I couldn't
find a protocol that offers the performance and scaling characteristics
that I desired. Namely, it should support multiple compression
contexts to facilitate scaling out to multiple CPU cores and
compression contexts should be able to live longer than single RPC
requests. HTTP/2 *almost* fits the bill. But the semantics of HTTP
message exchange state that streams can only live for a single
request-response. We /could/ tunnel on top of HTTP/2 streams and
frames with HEADER and DATA frames. But there's no guarantee that
HTTP/2 libraries and proxies would allow us to use HTTP/2 streams
and frames without the HTTP message exchange semantics defined in
RFC 7540 Section 8. Other RPC protocols like gRPC tunnel are built
on top of HTTP/2 and thus preserve its semantics of stream per
RPC invocation. Even QUIC does this. We could attempt to invent a
higher-level stream that spans HTTP/2 streams. But this would be
violating HTTP/2 because there is no guarantee that HTTP/2 streams
are routed to the same server. The best we can do - which is what
this protocol does - is shoehorn all request and response data into
a single HTTP message and create streams within. At that point, we've
defined a Content-Type in HTTP parlance. It just so happens our
media type can also work as a standalone, stream-based protocol,
without leaning on HTTP or similar protocol.
Differential Revision: https://phab.mercurial-scm.org/D2907
Augie Fackler <raf@durin42.com> [Wed, 04 Apr 2018 10:35:09 -0400] rev 37287
Added signature for changeset
7de7bd407251
Augie Fackler <raf@durin42.com> [Wed, 04 Apr 2018 10:35:09 -0400] rev 37286
Added tag 4.5.3 for changeset
7de7bd407251
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 26 Mar 2018 13:57:22 -0700] rev 37285
wireproto: start to associate frame generation with a stream
An upcoming commit will introduce "streams" into the frame-based wire
protocol. In preparation for this invasive change, we introduce a basic
"stream" class and have all operations that create frames also operate
alongside a stream instance.
Differential Revision: https://phab.mercurial-scm.org/D2906
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 26 Mar 2018 13:51:22 -0700] rev 37284
tests: fix duplicate and failing test
There were two "testconflictingrequestid" methods. Naturally this isn't
an error in Python. And by our luck, the test was failing.
So we rename the test and fix it to pass.
As part of this, _sendsingleframe() now takes a frame, not a string
describing the frame. This is better because action at a distance can
be confusing.
Differential Revision: https://phab.mercurial-scm.org/D2950
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 02 Apr 2018 16:47:53 -0700] rev 37283
debugcommands: drop offset and length from debugindex by default
These fields are an implementation detail of revlog storage. As
such, they are not part of the generic storage "index" interface
and shouldn't be displayed by default.
Because we don't have another way to display these fields, we've
retained support for printing these fields via --verbose.
Yes, I know we should probably be doing all this formatting using
modern formatting/templater APIs. I didn't feel like scope
bloating this patch.
Differential Revision: https://phab.mercurial-scm.org/D3028
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 02 Apr 2018 16:28:20 -0700] rev 37282
debugcommands: drop base revision from debugindex
Revlog index data consists of generic index metadata that will
likely be implemented across all storage engines and revlog-specifc
metadata.
Most tests printing index data only care about the generic fields.
This commit drops the printing of the base revision from
`hg debugindex`. This value is an implementation detail of
revlogs / delta chains. If tests are interested in verifying this
implementation detail, `hg debugdeltachain` is a better command.
Most tests were skipping over this field anyway. Tests that weren't
looked like they were newer. So my guess is we forgot to make them
skip the field to match the style of the older tests. This reinforces
my belief that the base revision is not worth having in
`hg debugindex`.
Differential Revision: https://phab.mercurial-scm.org/D3027
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 02 Apr 2018 16:24:57 -0700] rev 37281
tests: use debugdeltachain where appropriate
Some tests are verifying delta chain type things. This metadata
has more to do with a revlog implementation details than index
data, which is theoretically generic.
This commit ports some tests to `hg debugdeltachain`, as it is the
more appropriate debug command for looking at delta metadata.
Differential Revision: https://phab.mercurial-scm.org/D3026
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 02 Apr 2018 15:55:50 -0700] rev 37280
tests: don't use revlog paths in tests
Debug commands operating on revlogs don't need the full revlog
path: they can accept the relative path to a tracked file or use
-c/-m to specify a changelog or manifest.
Not using the revlog path makes tests more resilient to cases
where revlogs aren't being used for storage.
Differential Revision: https://phab.mercurial-scm.org/D3025
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 21:03:16 +0900] rev 37279
templater: define interface for objects requiring unwrapvalue()
unwrapvalue() is changed to not return a lazy bytes generator for "wrapped"
types because I want to define the tovalue() interface as such. It's a baby
step to unify unwrapvalue() and _unwrapvalue().
Yuya Nishihara <yuya@tcha.org> [Fri, 23 Mar 2018 21:40:16 +0900] rev 37278
templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org> [Sun, 18 Mar 2018 23:14:21 +0900] rev 37277
templater: pass (context, mapping) down to unwrapvalue()
The same reason as why I made unwraphybrid() take a (context, mapping) pair.
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 20:58:28 +0900] rev 37276
templater: drop unneeded generator from mappable object
Per the definition of the show() interface, it can return a bytes.
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 20:56:42 +0900] rev 37275
templater: mark .gen as a private attribute
Yuya Nishihara <yuya@tcha.org> [Sun, 18 Mar 2018 00:11:36 +0900] rev 37274
templatekw: do not directly call .gen
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 20:52:50 +0900] rev 37273
templater: define interface for objects requiring unwraphybrid()
Prepares for introducing another hybrid-like data type. show() takes context
as an argument so a wrapper class may render its items by pre-configured
template:
def show(self, context, mapping):
return (context.expand(self._tmpl, mapping + lm) for lm in self._mappings)
Yuya Nishihara <yuya@tcha.org> [Sat, 17 Mar 2018 20:09:05 +0900] rev 37272
templater: pass (context, mapping) down to unwraphybrid()
See the subsequent patches for why.
I initially thought it would be wrong to pass a mapping to flatten() and
stringify() since these functions may be applied to a tree of generators,
where each node should be bound to the mapping when it was evaluated. But,
actually that isn't a problem. If an intermediate node has to override a
mapping dict, it can do on unwraphybrid() and yield "unwrapped" generator
of byte strings:
"{f(g(v))}" # literal template example.
^^^^ # g() want to override a mapping, so it returns a wrapped
# object 'G{V}' with partial mapping 'lm' attached.
^^^^^^^ # f() stringifies 'G{V}', starting from a mapping 'm'.
# when unwrapping 'G{}', it updates 'm' with 'lm', and
# passes it to 'V'.
This structure is important for the formatter (and the hgweb) to build a
static template keyword, which can't access a mapping dict until evaluation
phase.
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 16:18:33 -0700] rev 37271
scmutil: add method for looking up a context given a revision symbol
changectx's constructor currently supports a mix if inputs:
* integer revnums
* binary nodeids
* '.', 'tip', 'null'
* stringified revnums
* namespaced identifiers (e.g. bookmarks and tags)
* hex nodeids
* partial hex nodeids
The first two are always internal [1]. The other five can be specified
by the user. The third type ('.', 'tip', 'null') often comes from
either the user or internal callers. We probably have some internal
callers that pass hex nodeids too, perhaps even partial ones
(histedit?). There are only a few callers that pass user-supplied
strings: revsets.stringset, peer.lookup, webutil.changeidctx, and
maybe one or two more.
Supporting this mix of things in the constructor is convenient, but a
bit strange, IMO. For example, if repo[node] is given a node that's
not in the repo, it will first check if it's bookmark etc before
raising an exception. Of course, the risk of it being a bookmark is
extremely small, but it just feels ugly.
Also, a problem with having this code in the constructor (whether it
supports a mix of types or not) is that it's harder to override (I'd
like to override it, and that's how this series started).
This patch starts moving out the handling of user-supplied strings by
introducing scmutil.revsymbol(). So far, that just checks that the
input is indeed a string, and then delegates to repo[symbol]. The
patch also calls it from revsets.stringset to prove that it works.
[1] Well, you probably can enter a 20-byte binary nodeid on the
command line, but I don't think we should care to preserve
support for that.
Differential Revision: https://phab.mercurial-scm.org/D3024
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 23:52:43 -0700] rev 37270
narrow: add trailing slash to dir earlier for debug{revlog,index,data}
The treemanifest code internally uses trailing slashes on directories
(except for the root directory, which is an empty string). We should
make sure we pass in directories with trailing slashes when we work
with the treemanifest code. For some reason, I seem to have decided to
be nice to the callers instead in
49c583ca48c4 (treemanifest: add
--dir option to debug{revlog,data,index}, 2015-04-12). Let's fix that
and pay the cost of fixing up the directory name close close to where
we get it from the user.
Differential Revision: https://phab.mercurial-scm.org/D3032
Sushil khanchi <sushilkhanchi97@gmail.com> [Sat, 31 Mar 2018 23:49:58 +0530] rev 37269
addremove: remove dry_run, similarity from scmutil.addremove (API)
Differential Revision: https://phab.mercurial-scm.org/D3000
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com> [Tue, 03 Apr 2018 12:16:19 +0530] rev 37268
histedit: make errror message translatable
This is a follow up patch to https://phab.mercurial-scm.org/D2394
As suggested by Yuya, this patch makes the error message translatable
Differential Revision: https://phab.mercurial-scm.org/D3031
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 09:18:01 -0700] rev 37267
context: drop support for changeid='' (API)
Since the previous commit, there seem to be no users who pass '' to
repo.__getitem__, so let's drop support for it.
It may seem like a small cost to keep support for it, but I've spent
time being confused by it twice already.
Differential Revision: https://phab.mercurial-scm.org/D3021
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 08:43:08 -0700] rev 37266
subrepo: use repo['.'] instead of repo['']
The "state" value (a revision) passed to abstractsubrepo.phase() can
be '' to represent the currently checked out revisions. Let's convert
that to the more common '.'.
I think this is the last of use of repo['.'] in core.
Differential Revision: https://phab.mercurial-scm.org/D3019
Martin von Zweigbergk <martinvonz@google.com> [Tue, 03 Apr 2018 00:12:29 +0530] rev 37265
children: use repo['.'] instead of repo['']
Differential Revision: https://phab.mercurial-scm.org/D3020
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 09:16:52 -0700] rev 37264
revset: drop support for '' as alias for '.'
Not marked BC because I think support for using '' on the CLI was
there by accident, and we don't seem to have documented it.
Differential Revision: https://phab.mercurial-scm.org/D3018
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 09:06:24 -0700] rev 37263
tests: add test showing current parse of empty string symbol in revset
We support e.g. parents(""), but I think that's by accident and I'll
change it soon.
Differential Revision: https://phab.mercurial-scm.org/D3017
Martin von Zweigbergk <martinvonz@google.com> [Mon, 02 Apr 2018 08:46:07 -0700] rev 37262
clone: rename "rev" to "revs" since there can be many
It was a little tricky in hg.clone(), since there was a local "revs"
variable defined there, but "rev" was never used after "revs", so I
just overwrote it.
Note that clonewithshare() should also have its "rev" argument renamed
to "revs", but I'll leave that to someone else.
Differential Revision: https://phab.mercurial-scm.org/D3016
Martin von Zweigbergk <martinvonz@google.com> [Sun, 01 Apr 2018 15:41:16 -0700] rev 37261
parseurl: consistently call second output "branches"
Differential Revision: https://phab.mercurial-scm.org/D3015
Yuya Nishihara <yuya@tcha.org> [Sun, 01 Apr 2018 11:06:29 +0900] rev 37260
templatefuncs: do not crash because of invalid value fed to mailmap()
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:34:15 -0700] rev 37259
scmutil: deprecate revpairnodes()
Differential Revision: https://phab.mercurial-scm.org/D3012
Martin von Zweigbergk <martinvonz@google.com> [Sun, 01 Apr 2018 09:30:44 -0700] rev 37258
tests: use context-return revpair() in autodiff
Differential Revision: https://phab.mercurial-scm.org/D3013
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:26:07 -0700] rev 37257
fileset: use context-returning revpair()
Differential Revision: https://phab.mercurial-scm.org/D3011
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:31:28 -0700] rev 37256
status: use context-returning revpair()
Differential Revision: https://phab.mercurial-scm.org/D3010
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:49:44 -0700] rev 37255
diff: simplify by converting contexts to nodeids a little later
Differential Revision: https://phab.mercurial-scm.org/D3009
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:25:02 -0700] rev 37254
diff: use context-returning revpair()
Differential Revision: https://phab.mercurial-scm.org/D3008
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:38:53 -0700] rev 37253
extdiff: use context-returning revpair()
Differential Revision: https://phab.mercurial-scm.org/D3007
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:10:46 -0700] rev 37252
scmutil: make revpair() return context objects (API)
Differential Revision: https://phab.mercurial-scm.org/D3006
Martin von Zweigbergk <martinvonz@google.com> [Sat, 31 Mar 2018 23:37:25 -0700] rev 37251
scmutil: introduce deprecated alias for revpair()
revsingle() returns a context object, revpair() returns nodeids,
revrange() returns integer revisions (in a revset). I'm going to
reduce this inconsistency by making revpair() return context
objects. Changing the return type is not nice to extensions, so this
patch introduces a nodeid-returning version of revpair() that they can
detect and use. Update callers to the new function so we can change
revpair() itself and then migrate them back one by one.
Differential Revision: https://phab.mercurial-scm.org/D3005
Matt Harbison <matt_harbison@yahoo.com> [Sat, 31 Mar 2018 23:58:08 -0400] rev 37250
lfs: ensure the transfer request is for a known URI
Since the dispatching code only checks the beginning of the string, this
enforces that there's only one more path component.
Matt Harbison <matt_harbison@yahoo.com> [Sat, 31 Mar 2018 23:47:56 -0400] rev 37249
lfs: avoid an improper usage of os.path.basename() to parse a URI
Matt Harbison <matt_harbison@yahoo.com> [Sat, 31 Mar 2018 15:20:43 -0400] rev 37248
lfs: add an experimental knob to disable blob serving
The use case here is the server admin may want to store the blobs elsewhere. As
it stands now, the `lfs.url` config on the client side is all that enforces this
(the web.allow-* permissions aren't able to block LFS blobs without also
blocking normal hg traffic). The real solution to this is to implement the
'verify' action on the client and server, but that's not a near term goal.
Whether this is useful in its own right, and should be promoted out of
experimental at some point is TBD.
Since the other two tests that deal with LFS and `hg serve` are already complex
and have #testcases, this seems like a good time to start a new test dedicated
to access checks against the server. Instead of conditionally wrapping the
wire protocol handler, I put this in the handler because I'd still like to bring
the annotations in from the evolve extension in order to set up the wrapping.
The 400 status probably isn't great, but that's what it would be for existing
`hg serve` instances without support for serving blobs.
Connor Sheehan <sheehan@mozilla.com> [Sat, 31 Mar 2018 13:01:20 -0400] rev 37247
stringutil: edit comment to reflect actual data type name
In development the data type used to hold an email/name pair
was called a "mailmaptup" since it was implemented as a
namedtuple. The implementation has since been changed to use
an @attr.s decorated class named mailmapping. This commit
changes a comment to reflect this change.
Differential Revision: https://phab.mercurial-scm.org/D3004
Connor Sheehan <sheehan@mozilla.com> [Sat, 31 Mar 2018 11:36:55 -0400] rev 37246
stringutil: improve check for failed mailmap line parsing
The existing check for a bad mailmap file entry fails with inputs
like b'>@<'. This commit adds a function to check if a sufficient
amount of information has been parsed from a mailmap file entry.
At minimum, one email must be found (assumed to be the commit email).
If email is not empty and no names are found, then there must be
two emails. If there are at least one email and name, the mapping
is valid.
Differential Revision: https://phab.mercurial-scm.org/D3003
Connor Sheehan <sheehan@mozilla.com> [Sat, 31 Mar 2018 10:21:39 -0400] rev 37245
stringutil: rename local email/names variables to their plural forms
email and name variables are renamed to emails and names (respectively).
This is because the email variable name shadows the email function
within the stringutil module. Since we are renaming email, we also rename
name for consistency.
Differential Revision: https://phab.mercurial-scm.org/D3002
Connor Sheehan <sheehan@mozilla.com> [Sat, 31 Mar 2018 10:13:42 -0400] rev 37244
templatefuncs: remove redundant "or author" from mailmap return statement
Differential Revision: https://phab.mercurial-scm.org/D3001
Matt Harbison <matt_harbison@yahoo.com> [Sat, 24 Feb 2018 19:56:59 -0500] rev 37243
lfs: add the 'Content-Type' header called out in the file transfer spec
https://github.com/git-lfs/git-lfs/blob/master/docs/api/basic-transfers.md#uploads
Matt Harbison <matt_harbison@yahoo.com> [Sun, 25 Feb 2018 23:44:02 -0500] rev 37242
lfs: improve the client message when the server signals an object error
Two things here. First, the previous message included a snippet of JSON, which
tends to be long (and in the case of lfs-test-server, has no error message).
Instead, give a concise message where possible, and leave the JSON to a debug
output. Second, the server can signal issues other than a missing individual
file. This change shows a corrupt file, but I'm debating letting the corrupt
file get downloaded, because 1) the error code doesn't really fit, and 2) having
it locally makes forensics easier. Maybe need a config knob for that.