Pulkit Goyal <pulkit@yandex-team.ru> [Wed, 03 Oct 2018 17:59:05 +0300] rev 40339
streamclone: pass narrowing related info in _walkstreamfiles()
This patch build a matcher using the include and exclude arguments we have in
generatev2() and pass that matcher into _walkstreamfiles(). This will help us
in filtering files we stream depending on the includes and excludes passed in
by the user.
Differential Revision: https://phab.mercurial-scm.org/D4851
Pulkit Goyal <pulkit@yandex-team.ru> [Wed, 26 Sep 2018 17:20:04 +0300] rev 40338
streamclone: new server config and some API changes for narrow stream clones
This patch introduces a new server config
`experimental.server.stream-narrow-clones` which if set to True will advertise
that the server supports narrow stream clones.
This patch also pass on the includes and excludes from getbundle command to
streamclone generation code.
There is a test added to show that the includepats and excludepats are correctly
passed.
Upcoming patches will implement storage layer filtering for streamclones and
then we can remove the temporary error and plug in the whole logic together to
make narrow stream clones working.
Differential Revision: https://phab.mercurial-scm.org/D5137
Pulkit Goyal <pulkit@yandex-team.ru> [Wed, 10 Oct 2018 17:36:59 +0300] rev 40337
narrow: only send the narrowspecs back if ACL in play
I am unable to think why we need to send narrowspecs back from the server. The
current state adds a 'narrow:spec' part to each changegroup which is generated
when narrow extension is enabled. So we are sending narrowspecs on pull also.
There is a problem with sending the narrowspecs the way we are doing it right
now. We add include and exclude as parameter of the 'narrow:spec' bundle2 part.
The the len of include or exclude string increase 255 which is obvious while
working on large repos, bundle2 generation code breaks. For more on that refer
issue5952 on bugzilla.
I was thinking why we need to send the narrowspecs back, and deleted the
'narrow:spec' bundle2 part generation code and found that only narrow-acl test
has some failure.
With this patch, we will only send the 'narrow:spec' bundle2 part if ACL is
enabled because the original narrowspecs in those cases can be a subset of
narrowspecs user requested.
There are phase related output change in couple of tests. The output change
shows that we are now dealing in public phases completely. So maybe sending the
narrow:spec bundle2 part was preventing phases being exchanged or phase bundle2
data being applied.
Differential Revision: https://phab.mercurial-scm.org/D4931
Anton Shestakov <av6@dwimlabs.net> [Wed, 17 Oct 2018 22:32:50 +0800] rev 40336
zsh_completion: add -l/--list flag for hg bookmarks completion
Flags in parentheses are mutually exclusive. Logic is taken from commands.py:
selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
if len(selactions) > 1:
raise error.Abort(_('--%s and --%s are incompatible')
% tuple(selactions[:2]))
...
if rev and action in {'delete', 'rename', 'list'}:
raise error.Abort(_("--rev is incompatible with --%s") % action)
if inactive and action in {'delete', 'list'}:
raise error.Abort(_("--inactive is incompatible with --%s") % action)
Differential Revision: https://phab.mercurial-scm.org/D5142
Anton Shestakov <av6@dwimlabs.net> [Wed, 17 Oct 2018 22:31:34 +0800] rev 40335
zsh_completion: fix a couple of flags still not being perfect
Differential Revision: https://phab.mercurial-scm.org/D5141
Anton Shestakov <av6@dwimlabs.net> [Wed, 17 Oct 2018 22:27:10 +0800] rev 40334
zsh_completion: use $_hg_remote_opts after it is defined
Before this patch, zsh wouldn't complete --ssh, --remotecmd or --insecure for
hg clone.
While at it, replace --uncompressed by --stream.
Differential Revision: https://phab.mercurial-scm.org/D5140
Martin von Zweigbergk <martinvonz@google.com> [Wed, 17 Oct 2018 11:56:03 -0700] rev 40333
tests: fix "running x tests using y ... " output in a few more places
These seem to have been missed by
1039404c5e1d (run-tests: print
number of tests and parallel process count, 2018-10-13).
Differential Revision: https://phab.mercurial-scm.org/D5145
Mark Thomas <mbthomas@fb.com> [Sun, 14 Oct 2018 09:34:21 +0000] rev 40332
py3: fix test-hardlinks.t
Differential Revision: https://phab.mercurial-scm.org/D5096
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 14 Sep 2018 14:56:13 -0700] rev 40331
exchange: support declaring pull depth
Upcoming commits will teach exchangev2 how to perform a shallow
clone. This commit teaches hg.clone(), exchange.pull(), and
exchange.pulloperation to recognize a request for a shallow clone
by having the caller specify a numeric depth of the maximum number of
ancestor changesets to fetch.
There are certainly other ways we could control shallow-ness. But this
one is simple to implement and is also how the narrow extension
controls things. So it seems to make sense to start here.
Differential Revision: https://phab.mercurial-scm.org/D5136
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 17 Oct 2018 10:10:05 +0200] rev 40330
exchangev2: support for calling rawstorefiledata to retrieve raw files
This is somewhat hacky. For that I apologize.
At the 4.8 Sprint, we decided we wanted to land support in wireprotov2 for doing
a partial clone with changelog and manifestlog bootstrapped from a "stream clone"
like primitive.
This commit implements the client-side bits necessary to facilitate that.
If the new server-side command for obtaining raw files data is available, we
call it to get the raw files for the changelog and manifestlog. Then we
fall through to an incremental pull. But when fetching files data, instead
of using the list of a changesets and manifests that we fetched via the
"changesetdata" command, we do a linear scan of the repo and resolve the
changeset and manifest nodes along with the manifest linkrevs.
Differential Revision: https://phab.mercurial-scm.org/D5135
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 16 Oct 2018 21:31:21 +0200] rev 40329
wireprotov2: implement command for retrieving raw store files
Implementing shallow clone of the changelog is hard. We want the 4.8
release to have a fast implementation of partial clone in wireprotov2. In
order to achieve fast, we can't use deltas for transferring changelog and
manifestlog data.
Per discussions at the 4.8 sprint, this commit implements a somwwhat hacky
and likely-to-be-changed-drastically-or-dropped command in wireprotov2 that
facilitates access to raw store files, namely the changelog and manifestlog.
Using this command, clients can perform a "stream clone" of sorts for just
the changelog and manifestlog. This will allow clients to fetch the changelog
and manifest revlogs, stream them to disk (which should be fast), then follow
up filesdata requests for files revision data for a particular changeset.
Differential Revision: https://phab.mercurial-scm.org/D5134
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 16 Oct 2018 21:35:33 +0200] rev 40328
wireprotov2: add response type that serializes to indefinite length bytestring
This will be needed in a future patch.
Differential Revision: https://phab.mercurial-scm.org/D5133
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 26 Sep 2018 14:38:43 -0700] rev 40327
exchangev2: recognize narrow patterns when pulling
pulloperation instances were recently taught to record file
include and exclude patterns to facilitate narrow file transfer.
Teaching the exchangev2 code to transfer a subset of files is
as simple as constructing a narrow matcher from these patterns and
filtering all seen file paths through it.
Keep in mind that this change only influences file data: we're
still fetching all changeset and manifest data. So, there's still
a ton of "partial clone" to implement in exchangev2.
On a personal note, I derive gratification that this feature requires
very few lines of new code to implement.
To test this, we implemented a minimal extension which allows us to specify
--include/--exclude to clone. While the narrow extension provides these
arguments, I explicitly wanted to test this functionality without the
narrow extension enabled, as that extension monkeypatches various things
and I want to isolate the behavior of core Mercurial.
Differential Revision: https://phab.mercurial-scm.org/D5132
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 09 Oct 2018 08:50:13 -0700] rev 40326
sqlitestore: file storage backend using SQLite
This commit provides an extension which uses SQLite to store file
data (as opposed to revlogs).
As the inline documentation describes, there are still several
aspects to the extension that are incomplete. But it's a start.
The extension does support basic clone, checkout, and commit
workflows, which makes it suitable for simple use cases.
One notable missing feature is support for "bundlerepos." This is
probably responsible for the most test failures when the extension
is activated as part of the test suite.
All revision data is stored in SQLite. Data is stored as zstd
compressed chunks (default if zstd is available), zlib compressed
chunks (default if zstd is not available), or raw chunks (if
configured or if a compressed delta is not smaller than the raw
delta). This makes things very similar to revlogs.
Unlike revlogs, the extension doesn't yet enforce a limit on delta
chain length. This is an obvious limitation and should be addressed.
This is somewhat mitigated by the use of zstd, which is much faster
than zlib to decompress.
There is a dedicated table for storing deltas. Deltas are stored
by the SHA-1 hash of their uncompressed content. The "fileindex" table
has columns that reference the delta for each revision and the base
delta that delta should be applied against. A recursive SQL query
is used to resolve the delta chain along with the delta data.
By storing deltas by hash, we are able to de-duplicate delta storage!
With revlogs, the same deltas in different revlogs would result in
duplicate storage of that delta. In this scheme, inserting the
duplicate delta is a no-op and delta chains simply reference the
existing delta.
When initially implementing this extension, I did not have
content-indexed deltas and deltas could be duplicated across files
(just like revlogs). When I implemented content-indexed deltas, the
size of the SQLite database for a full clone of mozilla-unified
dropped:
before: 2,554,261,504 bytes
after: 2,488,754,176 bytes
Surprisingly, this is still larger than the bytes size of revlog
files:
revlog files: 2,104,861,230 bytes
du -b: 2,254,381,614
I would have expected storage to be smaller since we're not limiting
delta chain length and since we're using zstd instead of zlib. I
suspect the SQLite indexes and per-column overhead account for the
bulk of the differences. (Keep in mind that revlog uses a 64-byte
packed struct for revision index data and deltas are stored without
padding. Aside from the 12 unused bytes in the 32 byte node field,
revlogs are pretty efficient.) Another source of overhead is file
name storage. With revlogs, file names are stored in the filesystem.
But with SQLite, we need to store file names in the database. This is
roughly equivalent to the size of the fncache file, which for the
mozilla-unified repository is ~34MB.
Since the SQLite database isn't append-only and since delta chains
can reference any delta, this opens some interesting possibilities.
For example, we could store deltas in reverse, such that fulltexts
are stored for newer revisions and deltas are applied to reconstruct
older revisions. This is likely a more optimal storage strategy for
version control, as new data tends to be more frequently accessed
than old data. We would obviously need wire protocol support for
transferring revision data from newest to oldest. And we would
probably need some kind of mechanism for "re-encoding" stores. But
it should be doable.
This extension is very much experimental quality. There are a handful
of features that don't work. It probably isn't suitable for day-to-day
use. But it could be used in limited cases (e.g. read-only checkouts
like in CI). And it is also a good proving ground for alternate
storage backends. As we continue to define interfaces for all things
storage, it will be useful to have a viable alternate storage backend
to see how things shake out in practice.
test-storage.py passes on Python 2 and introduces no new test failures on
Python 3. Having the storage-level unit tests has proved to be insanely
useful when developing this extension. Those tests caught numerous bugs
during development and I'm convinced this style of testing is the way
forward for ensuring alternate storage backends work as intended. Of
course, test coverage isn't close to what it needs to be. But it is
a start. And what coverage we have gives me confidence that basic store
functionality is implemented properly.
Differential Revision: https://phab.mercurial-scm.org/D4928
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 16 Oct 2018 15:36:19 +0200] rev 40325
storageutil: extract most of peek_censored from revlog
This function is super hacky and isn't correct 100% of the time. I'm going
to need this functionality on a future non-revlog store.
Let's copy things to storageutil so this code only exists once.
Differential Revision: https://phab.mercurial-scm.org/D5118
Matt Harbison <matt_harbison@yahoo.com> [Thu, 20 Sep 2018 17:27:01 -0700] rev 40324
lfs: autoload the extension when cloning from repo with lfs enabled
This is based on a patch by Gregory Szorc. I made small adjustments to
clean up the messaging when the server has the extension enabled, but the
client has it disabled (to prevent autoloading). Additionally, I added
a second server capability to distinguish between the server having the
extension enabled, and the server having LFS commits. This helps prevent
unnecessary requirement propagation- the client shouldn't add a requirement
that the server doesn't have, just because the server had the extension
loaded. The TODO I had about advertising a capability when the server can
natively serve up blobs isn't relevant anymore (we've had 2 releases that
support this), so I dropped it.
Currently, we lazily add the "lfs" requirement to a repo when we first
encounter LFS data. Due to a pretxnchangegroup hook that looks for LFS
data, this can happen at the end of clone.
Now that we have more control over how repositories are created, we can
do better.
This commit adds a repo creation option to add the "lfs" requirement.
hg.clone() sets this creation option if the remote peer is advertising
lfs usage (as opposed to just support needed to push).
So, what this change effectively does is have cloned repos
automatically inherit the "lfs" requirement.
Differential Revision: https://phab.mercurial-scm.org/D5130
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 16 Oct 2018 16:24:46 +0200] rev 40323
testing: switch to inserting deltas
As the comment in the test specifies, this was relying on storage backend
implementation details. We switch to inserting a raw delta, skipping the
regular insert path to ensure we have the desired outcome. This required
implementing support for handling deltas in the revlog testing code.
Differential Revision: https://phab.mercurial-scm.org/D5116
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 16 Oct 2018 15:24:06 +0200] rev 40322
testing: remove expectation of error on bad node insert
addgroup() doesn't necessarily validate the hashes of each incoming revision.
This is an optimization that allows delta group application to complete faster.
The fact that revlog raises in this particular test is an implementation detail
due to the way revlogs are testing multiple deltas.
Differential Revision: https://phab.mercurial-scm.org/D5115
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 16 Oct 2018 17:45:39 +0200] rev 40321
storageutil: convert fileid to bytes to avoid cast to %s
test-storage.py manages to trigger this on Python 3.
Differential Revision: https://phab.mercurial-scm.org/D5117
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 16 Oct 2018 17:48:28 +0200] rev 40320
tests: use byte literals in test-storage.py
This fixes a Python 3 breakage due to unknown key due to str/bytes type
mismatch.
# skip-blame just b'' literals
Differential Revision: https://phab.mercurial-scm.org/D5114
Yuya Nishihara <yuya@tcha.org> [Tue, 16 Oct 2018 07:19:38 +0200] rev 40319
py3: byte-stringify literals in test-keyword.t
# skip-blame just some b'' prefixes
Yuya Nishihara <yuya@tcha.org> [Tue, 16 Oct 2018 07:18:30 +0200] rev 40318
py3: flush std streams before/after running user code in heredoctest.py
Otherwise, things written to stdout.buffer would be interleaved.
Yuya Nishihara <yuya@tcha.org> [Tue, 16 Oct 2018 08:06:17 +0200] rev 40317
py3: rewrite StringIO fallback for Python 3
Yuya Nishihara <yuya@tcha.org> [Tue, 16 Oct 2018 07:04:07 +0200] rev 40316
py3: reinvent print() function for contrib/hgclient.py